/**
 * @desc 函数节流
 * 如果某个事件会被频繁触发，那么节流函数会按照一定的频率来执行函数；
 * 不管在这个中间有多少次触发这个事件，执行函数的频率总是固定的。
 
 * @example 适用场景：
 *  鼠标移动事件
 *  王者荣耀攻击键, 点击再快也是以一定攻速(频率)进行攻击
 
 * @param  {func} Function 要节流的函数。
 * @param  {interval} number 时间间隔。
 * @param  {options} object 选项。
 *   e.g. 首次不触发leading和最后结束触发trailing: options = { leading: true, trailing: false }
 * @return {Function} 新的节流函数。
 */

function throttle(fn, interval = 200, options = { leading: true, trailing: false }) {
  // 1.记录上一次的开始时间
  const { leading, trailing } = options
  let lastTime = 0
  let timer = null
  // 2.事件触发时, 真正执行的函数
  const _throttle = function() {
    // 2.1.获取当前事件触发时的时间
    const nowTime = new Date().getTime()
    if (!lastTime && !leading) lastTime = nowTime
    // 2.2.使用当前触发的时间和之前的时间间隔以及上一次开始的时间, 计算出还剩余多长事件需要去触发函数
    const remainTime = interval - (nowTime - lastTime)
    if (remainTime <= 0) {
      if (timer) {
        clearTimeout(timer)
        timer = null
      }
      // 2.3.真正触发函数
      fn()
      // 2.4.保留上次触发的时间
      lastTime = nowTime
      return
    }
    if (trailing && !timer) {
      timer = setTimeout(() => {
        timer = null
        lastTime = !leading ? 0 : new Date().getTime()
        fn()
      }, remainTime)
    }
  }
  return _throttle
}

export { throttle };